Option Explicit On
Option Strict On

Imports System.Collections.Generic
Imports NStl.Arithmetic
Imports NUnit.Framework
Imports NStl.Iterators.Support

Imports NStl
Imports NStl.SyntaxHelper
Imports NStl.Linq
Imports System.Linq
Imports NUnit.Framework.SyntaxHelpers

Namespace nstl.test
    <TestFixture()> _
    Public Class AlgorithmTest


        <Test()> _
        Public Sub find_if()
            'find_if_input_it()
            find_if_fwd_it()
            find_if_rand_it()
        End Sub
        Public Sub find_if_rand_it()
            Dim v1 As New List(Of Integer)(New Integer() {-2, -1, 0, 1, 2, 3, 4})

            'Test forward iterator version
            Dim pos As ListTIterator(Of Integer) = _
               Algorithm.FindIf(v1.Begin(), v1.End(), Bind.Second(Compare.Greater(Of Integer)(), 1))
            Assert.IsTrue(v1.Begin.DistanceTo(pos) = 4)


            pos = Algorithm.FindIf(v1.Begin, v1.End, Bind.Second(Compare.GreaterEqual(Of Integer)(), 3))
            Assert.IsTrue(v1.Begin.DistanceTo(pos) = 5)

            pos = Algorithm.FindIf(v1.Begin, v1.End, Bind.Second(Compare.GreaterEqual(Of Integer)(), 42))
            Assert.AreEqual(v1.End(), pos)
        End Sub
        Private Sub find_if_fwd_it()
            Dim v1 As New List(Of Integer)(New Integer() {-2, -1, 0, 1, 2, 3, 4})

            'Test forward iterator version
            Dim pos As ForwardIteratorProxy(Of Integer) = _
               Algorithm.FindIf(New ForwardIteratorProxy(Of Integer)(v1.Begin), New ForwardIteratorProxy(Of Integer)(v1.End), Bind.Second(Compare.Greater(Of Integer)(), 1))
            Assert.IsTrue(New ForwardIteratorProxy(Of Integer)(v1.Begin).DistanceTo(pos) = 4)


            pos = Algorithm.FindIf(New ForwardIteratorProxy(Of Integer)(v1.Begin), New ForwardIteratorProxy(Of Integer)(v1.End), Bind.Second(Compare.GreaterEqual(Of Integer)(), 3))
            Assert.IsTrue(New ForwardIteratorProxy(Of Integer)(v1.Begin).DistanceTo(pos) = 5)

            pos = Algorithm.FindIf(New ForwardIteratorProxy(Of Integer)(v1.Begin), New ForwardIteratorProxy(Of Integer)(v1.End), Bind.Second(Compare.GreaterEqual(Of Integer)(), 42))
            Assert.AreEqual(New ForwardIteratorProxy(Of Integer)(v1.End()), pos)
        End Sub



        <Test()> _
        Public Sub find()
            Dim v1 As New List(Of Integer)(New Integer() {-2, -1, 0, 1, 2, 3, 4})

            'Test forward iterator version
            Dim pos As ListTIterator(Of Integer) = Algorithm.Find(v1.Begin, v1.End, 1)
            Assert.AreNotEqual(pos, v1.End())
            Dim i As Integer = v1.Begin.DistanceTo(pos)
            Assert.IsTrue(v1.Begin.DistanceTo(pos) = 3)
            Assert.AreEqual(pos.Value, 1)

            pos = Algorithm.FindIf(v1.Begin, v1.End, Bind.Second(Compare.GreaterEqual(Of Integer)(), 42))
            Assert.AreEqual(v1.End(), pos)
        End Sub
        <Test()> _
        Public Sub remove_copy_if()
            Dim v1 As New List(Of Integer)(New Integer() {7, 1, 9, 2, 0, 7, 7, 3, 4, 6, 8, 5, 7, 7})
            Dim v2 As New List(Of Integer)()
            Algorithm.RemoveCopyIf(v1.Begin, v1.End, v2.AddInserter(), Bind.Second(Compare.GreaterEqual(Of Integer), 7))
            Assert.IsTrue(TestUtil.equal(v2, New List(Of Integer)(New Integer() {1, 2, 0, 3, 4, 6, 5})))
        End Sub
        <Test()> _
        Public Sub remove_copy()
            Dim v1 As New List(Of Integer)(New Integer() {7, 1, 9, 2, 0, 7, 7, 3, 4, 6, 8, 5, 7, 7})
            Dim v2 As New List(Of Integer)
            Algorithm.RemoveCopy(v1.Begin, v1.End, v2.AddInserter(), 7)
            Assert.IsTrue(TestUtil.equal(v2, New List(Of Integer)(New Integer() {1, 9, 2, 0, 3, 4, 6, 8, 5})))
        End Sub
        '<Test()> _
        'Public Sub remove_if()
        '    Dim v1 As New List(Of Integer)(New Integer() {7, 1, 9, 2, 0, 7, 7, 3, 4, 6, 8, 5, 7, 7})
        '    v1.Erase(Algorithm.RemoveIf(v1.Begin, v1.End, Bind.Second(Compare.Greater(Of Integer)(), 3)), v1.End())
        '    Assert.IsTrue(TestUtil.equal(v1, New List(Of Integer)(New Integer() {1, 2, 0, 3})))
        'End Sub
        '<Test()> _
        'Public Sub remove()
        '    Dim v1 As New List(Of Integer)(New Integer() {7, 1, 9, 2, 0, 7, 7, 3, 4, 6, 8, 5, 7, 7})
        '    v1.Erase(Algorithm.Remove(v1.Begin, v1.End, 7), v1.End())
        '    Assert.IsTrue(TestUtil.equal(v1, New List(Of Integer)(New Integer() {1, 9, 2, 0, 3, 4, 6, 8, 5})))
        'End Sub
        <Test()> _
        Public Sub copy()
            Dim v1 As New LinkedList(Of Integer)(New Integer() {7, 1, 9, 2, 0, 7, 7, 3, 4, 6, 8, 5, 7, 7})
            Dim v2 As New List(Of Integer)
            v2.Resize(v1.Count)
            Dim i As ListTIterator(Of Integer) = Algorithm.Copy(v1.Begin, v1.End, v2.Begin())
            Assert.That(v1, Iz.EqualTo(v2))
        End Sub
        <Test()> _
        Public Sub copy_if()
            Dim v1 As New LinkedList(Of Integer)(New Integer() {7, 1, 9, 2, 0, 7, 7, 3, 4, 6, 8, 5, 7, 7})
            Dim v2 As New List(Of Integer)
            Algorithm.CopyIf(v1.Begin, v1.End, v2.AddInserter(), Bind.Second(Compare.Greater(Of Integer)(), 4))
            Assert.IsTrue(TestUtil.equal(v2, 7, 9, 7, 7, 6, 8, 5, 7, 7))
        End Sub
        <Test()> _
        Public Sub set_difference()
            Dim v1 As New LinkedList(Of Integer)(New Integer() {-1, 0, 1, 2, 3, 4})
            Dim v2 As New List(Of Integer)(New Integer() {-3, -2, -1, 0})
            Dim v3 As New List(Of Integer)

            Algorithm.SetDifference(v1.Begin, v1.End, v2.Begin, v2.End, v3.AddInserter(), Compare.Less(Of Integer)())
            Assert.IsTrue(TestUtil.equal(v3, 1, 2, 3, 4))

            ' using a different sorter
            v1 = New LinkedList(Of Integer)(New Integer() {0, -1, 1, 2, 3, 4})
            v2 = New List(Of Integer)(New Integer() {0, -1, -2, -3})
            v3 = New List(Of Integer)

            Algorithm.SetDifference(v1.Begin, v1.End, v2.Begin, v2.End, v3.AddInserter(), New mod_less_int())
            Assert.IsTrue(TestUtil.equal(v3, 1, 4))
        End Sub
        <Test()> _
        Public Sub set_intersection()
            Dim l1 As New LinkedList(Of Integer)(New Integer() {-1, 0, 1, 2, 3})
            Dim v2 As New List(Of Integer)(New Integer() {-3, -2, -1, 0, 1})
            Dim v3 As New List(Of Integer)

            Algorithm.SetIntersection(l1.Begin, l1.End, v2.Begin, v2.End, v3.AddInserter(), Compare.Less(Of Integer)())
            Assert.IsTrue(TestUtil.equal(v3, -1, 0, 1))

            ' using a different sorter
            l1 = New LinkedList(Of Integer)(New Integer() {0, -1, 1, 2, 3})
            v2 = New List(Of Integer)(New Integer() {0, -1, 1, -2, -3})
            v3 = New List(Of Integer)

            Algorithm.SetIntersection(l1.Begin, l1.End, v2.Begin, v2.End, v3.AddInserter(), New mod_less_int())
            Assert.IsTrue(TestUtil.equal(v3, 0, -1, 1, 2, 3))
        End Sub
        <Test()> _
            Public Sub set_symmetric_difference()
            Dim v1 As New LinkedList(Of Integer)(New Integer() {-1, 0, 1, 2, 3, 4})
            Dim v2 As New List(Of Integer)(New Integer() {-3, -2, -1, 0})
            Dim v3 As New List(Of Integer)

            Algorithm.SetSymmetricDifference(v1.Begin, v1.End, v2.Begin, v2.End, v3.AddInserter(), Compare.Less(Of Integer)())
            Assert.IsTrue(TestUtil.equal(v3, -3, -2, 1, 2, 3, 4))

            ' using a different sorter
            v1 = New LinkedList(Of Integer)(New Integer() {0, -1, 1, 2, 3, 4})
            v2 = New List(Of Integer)(New Integer() {0, -1, -2, -3})
            v3 = New List(Of Integer)

            Algorithm.SetSymmetricDifference(v1.Begin, v1.End, v2.Begin, v2.End, v3.AddInserter(), New mod_less_int())
            Assert.IsTrue(TestUtil.equal(v3, 1, 4))
        End Sub
        <Test()> _
        Public Sub set_union()
            Dim v1a As New LinkedList(Of Integer)(New Integer() {-1, 0, 1, 2, 3})
            Dim v1b As New List(Of Integer)(New Integer() {-3, -2, -1, 0, 1})
            Dim v1c As New List(Of Integer)
            Algorithm.SetUnion(v1a.Begin, v1a.End, v1b.Begin, v1b.End, v1c.AddInserter(), Compare.Less(Of Integer)())

            Assert.IsTrue(TestUtil.equal(v1c, -3, -2, -1, 0, 1, 2, 3))
        End Sub
        <Test()> _
        Public Sub transform1()
            Dim v1 As New List(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, 6, 7, 8, 9})
            Dim v2 As New LinkedList(Of Single)
            Algorithm.Transform(v1.Begin, v1.End, v2.AddInserter(), New int2single())

            Dim expected As Single() = New Single() {0.0F, 1.0F, 2.0F, 3.0F, 4.0F, 5.0F, 6.0F, 7.0F, 8.0F, 9.0F}
            Assert.That(v2, Iz.EqualTo(expected))
        End Sub
        <Test()> _
        Public Sub transform2()
            Dim v1 As New List(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, 6, 7, 8, 9})
            Dim v2 As New LinkedList(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14})
            Dim v3 As New List(Of Single)
            Algorithm.Transform(v1.Begin, v1.End, v2.Begin, v3.AddInserter(), New int2single())
            Assert.IsTrue(TestUtil.equal(v3, 0.0F, 2.0F, 4.0F, 6.0F, 8.0F, 10.0F, 12.0F, 14.0F, 16.0F, 18.0F))
        End Sub
        <Test()> _
        Public Sub adjacent_find()
            Dim ints As Integer() = {1, 2, 3, 4, 4, 5, 6, 7}
            'Find the first pair of matching consecutive elements
            'in the range [first, last]
            'This version performs matching using equal_to
            Dim location As ListIterator(Of Integer) = Algorithm.AdjacentFind(ints.Begin(), ints.End(), Compare.EqualTo(Of Integer)())
            Assert.IsTrue(Not location.Equals(ints.End()))
            Assert.AreEqual(location.Value, 4)
        End Sub
        <Test()> _
        Public Sub lower_bound()
            Dim numbers As Integer() = {4, 10, 70, 10, 30, 69, 96, 100}

            'sort the array, usng on board capabilities
            Array.Sort(numbers) '4,10,10,30,69,70,96,100

            Dim location As ListIterator(Of Integer) = Algorithm.LowerBound(numbers.Begin(), numbers.End(), 10, Compare.Less(Of Integer)())
            Assert.AreNotEqual(location, numbers.End())
            Assert.AreEqual(location.Value, 10)
            Assert.IsTrue(numbers.Begin().DistanceTo(location) = 1)

            location = Algorithm.LowerBound(numbers.Begin(), numbers.End(), 1, Compare.Less(Of Integer)())
            Assert.AreNotEqual(location, numbers.End())
            Assert.AreEqual(location.Value, 4)

            location = Algorithm.LowerBound(numbers.Begin(), numbers.End(), 5, Compare.Less(Of Integer)())
            Assert.AreNotEqual(location, numbers.End())
            Assert.AreEqual(location.Value, 10)

            location = Algorithm.LowerBound(numbers.Begin(), numbers.End(), 200, Compare.Less(Of Integer)())
            Assert.AreEqual(location, numbers.End())

            location = Algorithm.LowerBound(numbers.Begin(), numbers.End(), 4, Compare.Less(Of Integer)())
            Assert.AreNotEqual(location, numbers.End())
            Assert.AreEqual(location.Value, 4)
        End Sub
        <Test()> _
        Public Sub binary_search()
            Dim numbers As Integer() = {50, 10, 30, 20, 25, 5}

            'sort the array, usng on board capabilities
            Array.Sort(numbers)
            Dim fwd As ListIterator(Of Integer) = Algorithm.BinarySearch(numbers.Begin(), numbers.End(), 10, Compare.Less(Of Integer)())
            Assert.AreNotEqual(fwd, (numbers.End()), "10 is NOT part of the range")
            Assert.IsTrue(numbers.Begin().DistanceTo(fwd) = 1, "FAILED")

            Dim numbers2 As Integer() = {3, 4, -1, 1, -2, 0, 2}
            Array.Sort(numbers2, New mod_less_int)

            Assert.AreNotEqual(Algorithm.BinarySearch(numbers2.Begin(), numbers2.End(), -3, New mod_less_int), numbers2.End(), "FAILED")
        End Sub
        <Test()> _
        Public Sub copy_backwards()
            Dim v1 As New List(Of Integer)
            Dim v2 As New LinkedList(Of Integer)
            For i As Integer = 0 To 5
                v1.Add(i * 10)
            Next
            For i As Integer = 0 To 10
                v2.AddLast(i * 3)
            Next

            Algorithm.CopyBackward(v1.Begin(), v1.Begin().Add(3), v2.Begin().Add(7))

            Algorithm.CopyBackward(v2.Begin().Add(4), v2.Begin().Add(7), v2.Begin().Add(9))


            'expected
            'v1 = ( 0 10 20 30 40 50 )
            'v2 = ( 0 3 6 9 12 15 18 21 24 27 30 )
            'v2 with v1 insert = ( 0 3 6 9 0 10 20 21 24 27 30 )
            'v2 with shifted insert = ( 0 3 6 9 0 10 0 10 20 27 30 )

            Dim expected As Integer() = {0, 3, 6, 9, 0, 10, 0, 10, 20, 27, 30}

            Assert.That(v2, Iz.EqualTo(expected))
        End Sub
        <Test()> _
        Public Sub count_if()
            Dim names As New List(Of String)
            names.Add("She")
            names.Add("Sells")
            names.Add("Sea")
            names.Add("Shells")
            names.Add("by")
            names.Add("the")
            names.Add("Sea")
            names.Add("Shore")

            'Count the Element with the letter S
            Dim countS As Integer = Algorithm.CountIf(names.Begin(), names.End(), Bind.Second(New MatchFirstChar, "S"c))
            Assert.AreEqual(countS, 6)
        End Sub
        <Test()> _
        Public Sub mismatch()
            Dim v1 As New List(Of Integer)(New Integer() {1, 2, 6, 5, 9, 8, 10, 33})
            Dim v2 As New LinkedList(Of Integer)(New Integer() {1, 2, 3, 4, 5, 6, 75, 88})
            Dim v3 As New List(Of Integer)(New Integer() {1, 2, 6, 5, 9, 8, 10, 33})

            Dim b As ListTIterator(Of Integer) = v1.Begin
            Dim res As System.Collections.Generic.KeyValuePair(Of ListTIterator(Of Integer), LinkedListIterator(Of Integer)) = _
                Algorithm.Mismatch(v1.Begin(), v1.End(), v2.Begin(), Compare.EqualTo(Of Integer)())
            Assert.IsFalse(res.Key.Equals(v1.End()))
            Assert.IsFalse(res.Value.Equals(v2.End()))

            Dim res2 As System.Collections.Generic.KeyValuePair(Of ListTIterator(Of Integer), ListTIterator(Of Integer)) = _
                 Algorithm.Mismatch(v1.Begin(), v1.End(), v3.Begin(), Compare.EqualTo(Of Integer)())
            Assert.IsTrue(res2.Key.Equals(v1.End()))
            Assert.IsTrue(res2.Value.Equals(v3.End()))

        End Sub
        <Test()> _
        Public Sub equal()
            Dim words As New List(Of String)
            words.Add("She")
            words.Add("Sells")
            words.Add("Sea")
            words.Add("Shells")
            words.Add("by")
            words.Add("the")
            words.Add("Sea")
            words.Add("Shore")

            'copy the vector
            Dim copiedWords As New LinkedList(Of String)
            Algorithm.Copy(words.Begin(), words.End(), copiedWords.AddInserter())

            Assert.IsTrue(Algorithm.Equal(words.Begin(), words.End(), copiedWords.Begin(), Compare.EqualTo(Of String)()))
        End Sub
        <Test()> _
        Public Sub equal_range()
            Dim v As New List(Of Integer)(New Integer() {-1, 0, 1, 2, 3, 4})

            Dim erange As Range(Of Integer, ListTIterator(Of Integer)) _
                            = Algorithm.EqualRange(v.Begin, v.End, 3, Compare.Less(Of Integer)())
            Assert.AreEqual(erange.Begin.Value, 3)
            Assert.AreEqual(erange.End.Value, 4)

            Dim v1 As New List(Of Integer)(New Integer() {-3, -2, -1, -1, 0, 0, 1, 2, 3, 4}) 'less
            Dim v2 As New List(Of Integer)(New Integer() {4, 3, 2, 1, 0, 0, -1, -1, -2, -3}) 'greater
            Dim v3 As New List(Of Integer)(New Integer() {0, 0, -1, -1, 1, -2, 2, -3, 3, 4}) 'mod_less

            erange = Algorithm.EqualRange(v1.Begin, v1.End, 3, Compare.Less(Of Integer)())
            Assert.AreEqual(erange.Begin.Value, 3)
            Assert.AreEqual(erange.End.Value, 4)
            Assert.IsTrue(TestUtil.equal(Of Integer)(erange, New Integer() {3}))

            erange = Algorithm.EqualRange(v2.Begin, v2.End, 3, Compare.Greater(Of Integer)())
            Assert.AreEqual(erange.Begin.Value, 3)
            Assert.AreEqual(erange.End.Value, 2)
            Assert.IsTrue(TestUtil.equal(Of Integer)(erange, New Integer() {3}))

            erange = Algorithm.EqualRange(v3.Begin, v3.End, 3, New mod_less_int())
            Assert.AreEqual(erange.Begin.Value, -3)
            Assert.AreEqual(erange.End.Value, 4)
            Assert.IsTrue(TestUtil.equal(Of Integer)(erange, New Integer() {-3, 3}))
        End Sub
        <Test()> _
        Public Sub upper_bound()
            Dim numbers As New List(Of Integer)(New Integer() {4, 10, 10, 30, 69, 70, 96, 100})

            Dim location As ListTIterator(Of Integer) = Algorithm.UpperBound(numbers.Begin, numbers.End, 10, Compare.Less(Of Integer)())
            Assert.AreNotEqual(location, numbers.End())
            Assert.AreEqual(location.Value, 30)
        End Sub
        <Test()> _
        Public Sub fill_n()
            Dim v As New List(Of Integer)()
            Algorithm.FillN(v.AddInserter(), 10, 42)
            Assert.IsTrue(TestUtil.equal(v, New Integer() {42, 42, 42, 42, 42, 42, 42, 42, 42, 42}))
        End Sub
        <Test()> _
        Public Sub pushHeap()
            Dim v1 As New List(Of Integer)(New Integer() {9, 2, 7, 3, 1, 6, 8, 4, 5})

            Algorithm.MakeHeap(v1.Begin(), v1.End(), Compare.Less(Of Integer)())

            v1.Add(10)

            Algorithm.PushHeap(v1.Begin, v1.End, Compare.Less(Of Integer)())

            Assert.IsTrue(TestUtil.equal(v1, New Integer() {10, 9, 8, 4, 5, 6, 7, 2, 3, 1}))

            Algorithm.MakeHeap(v1.Begin(), v1.End(), Compare.Greater(Of Integer)())

            v1.Add(0)
            Algorithm.PushHeap(v1.Begin, v1.End, Compare.Greater(Of Integer)())

            Assert.IsTrue(TestUtil.equal(v1, New Integer() {0, 1, 6, 3, 2, 8, 7, 4, 10, 9, 5}))
        End Sub
        <Test()> _
        Public Sub makeHeap()
            Dim v1 As New List(Of Integer)(New Integer() {8, 1, 9, 2, 0, 5, 7, 3, 4, 6})

            Algorithm.MakeHeap(v1.Begin(), v1.End())


            Assert.IsTrue(TestUtil.equal(v1, New Integer() {9, 6, 8, 4, 1, 5, 7, 3, 2, 0}))

            Algorithm.MakeHeap(v1.Begin(), v1.End(), Compare.Greater(Of Integer)())
            Assert.IsTrue(TestUtil.equal(v1, New Integer() {0, 1, 5, 2, 6, 8, 7, 3, 4, 9}))
        End Sub
        <Test()> _
       Public Sub popHeap()
            Dim v1 As New List(Of Integer)(New Integer() {9, 2, 7, 3, 1, 6, 8, 4, 5})

            Algorithm.MakeHeap(v1.Begin, v1.End)

            v1.Add(10)
            Algorithm.PushHeap(v1.Begin(), v1.End())

            'Remove the largest element from the heap
            Algorithm.PopHeap(v1.Begin(), v1.End())
            Assert.IsFalse(TestUtil.mismatch(v1, New Integer() {9, 5, 8, 4, 1, 6, 7, 2, 3, 10}))


            'Make v1 a heap with greater-than ordering with a 0 element
            Algorithm.MakeHeap(v1.Begin(), v1.End(), Compare.Greater(Of Integer)())
            v1.Add(0)
            'Application of popHeap to remove the smallest element
            Algorithm.PushHeap(v1.Begin(), v1.End(), Compare.Greater(Of Integer)())

            Algorithm.PopHeap(v1.Begin(), v1.End(), Compare.Greater(Of Integer)())

            Assert.IsFalse(TestUtil.mismatch(v1, New Integer() {1, 2, 6, 3, 5, 8, 7, 4, 9, 10, 0}))
        End Sub
        <Test()> _
        Public Sub sortHeap()
            Dim v1 As New List(Of Integer)(New Integer() {9, 2, 7, 3, 1, 6, 8, 4, 5})

            'Algorithm.makeHeap(v1.begin, v1.end)
            Algorithm.SortHeap(v1.Begin, v1.End, Compare.Less(Of Integer)())
            Assert.IsFalse(TestUtil.mismatch(v1, New List(Of Integer)(New Integer() {1, 2, 3, 4, 5, 6, 8, 7, 9})))
        End Sub
        <Test()> _
        Public Sub partial_sort()
            Dim v As New List(Of Integer)(New Integer() {0, 2, 4, 6, 8, 10, 1, 3, 5, 7, 9, 11})

            Algorithm.PartialSort(v.Begin, v.Begin() + 6, v.End)
            Assert.IsFalse(TestUtil.mismatch(v, New List(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, 10, 8, 6, 7, 9, 11})))

            Algorithm.PartialSort(v.Begin, v.Begin() + 4, v.End, Compare.Greater(Of Integer)())
            Assert.IsFalse(TestUtil.mismatch(v, New List(Of Integer)(New Integer() {11, 10, 9, 8, 0, 1, 2, 3, 4, 5, 6, 7})))

            Algorithm.PartialSort(v.Begin, v.Begin() + 8, v.End, New UDgreater)
            Assert.IsFalse(TestUtil.mismatch(v, New List(Of Integer)(New Integer() {11, 10, 9, 8, 7, 6, 5, 4, 0, 1, 2, 3})))
        End Sub

        <Test()> _
        Public Sub search()

            Dim v1 As New List(Of Integer)(New Integer() {0, 5, 10, 15, 20, 25, 0, 5, 10, 15, 20, 25})
            Dim l1 As New LinkedList(Of Integer)(New Integer() {20, 25})
            Dim v2 As New LinkedList(Of Integer)(New Integer() {20, 30, 40})

            Dim pos As ListTIterator(Of Integer) = _
                Algorithm.Search(Of Integer, ListTIterator(Of Integer))(v1.Begin, v1.End, l1.Begin, l1.End)
            Assert.IsTrue(Not pos.Equals(v1.End))
            Assert.IsTrue(CType(pos.Value, Integer) = 20)

            pos = Algorithm.Search(v1.Begin, v1.End, v2.Begin, v2.End, New equal_twice)
            Assert.IsTrue(Not pos.Equals(v1.End))
            Assert.IsTrue(CType(pos.Value, Integer) = 10)

            pos = Algorithm.Search(pos + 1, v1.End, v2.Begin, v2.End, New equal_twice)
            Assert.IsTrue(Not pos.Equals(v1.End))
            Assert.IsTrue(CType(pos.Value, Integer) = 10)

        End Sub
        <Test()> _
        Public Sub search_n()
            Dim v1 As New List(Of Integer)(New Integer() {0, 5, 10, 15, 20, 25, 5, 5, 5, 0, 5, 10, 10, 10, 25, 5, 5, 5})

            Dim r1 As ListTIterator(Of Integer) = Algorithm.SearchN(v1.Begin, v1.End, 3, 5, Compare.EqualTo(Of Integer)())
            Assert.AreNotEqual(r1, v1.End())
            Assert.IsTrue(v1.Begin().DistanceTo(r1) = 6)

            r1 = Algorithm.SearchN(v1.Begin, v1.End, 3, 20, New equal_twice)
            Assert.AreNotEqual(r1, v1.End())
            Assert.IsTrue(v1.Begin().DistanceTo(r1) = 11)

        End Sub


        <Test()> _
        Public Sub find_end()

            Dim v1 As New List(Of Integer)(New Integer() {0, 5, 10, 15, 20, 25, 0, 5, 10, 15, 20, 25})
            '                                             0  1   2   3   4   5  6  7   8   9  10  11   12
            Dim l1 As New LinkedList(Of Integer)(New Integer() {5, 10, 15, 20})
            Dim v2 As New List(Of Integer)(New Integer() {20, 30, 40})
            Dim v3 As New List(Of Integer)(New Integer() {100, 200, 300})

            Dim result As ListTIterator(Of Integer) = Algorithm.FindEnd(v1.Begin, v1.End, l1.Begin, l1.End, Compare.EqualTo(Of Integer)())
            Assert.AreEqual(result.Value, l1.First().Value)
            Assert.AreEqual(v1.Begin.DistanceTo(result), 7)

            result = Algorithm.FindEnd(v1.Begin, v1.End, v2.Begin, v2.End, New equal_twice)
            Assert.AreEqual(result.Value, CType(v2.First() / 2, Integer))
            Assert.AreEqual(v1.Begin.DistanceTo(result), 8)

            result = Algorithm.FindEnd(v1.Begin, v1.End, v3.Begin, v3.End, Compare.EqualTo(Of Integer)())
            Assert.AreEqual(result, v1.End())
        End Sub
        <Test()> _
        Public Sub find_first_of()

            Dim v1 As New List(Of Integer)(new Integer() {0, 5, 10, 15, 20, 25, 0, 5, 10, 15, 20, 25})
            '                                0  1   2   3   4   5   6 7   8   9  10  11   12
            Dim l1 As New LinkedList(Of Integer)(New Integer() {15, 20})
            Dim v2 As New List(Of Integer)(new Integer() {20, 30, 40})

            Dim result As ListTIterator(Of Integer) = Algorithm.FindFirstOf(v1.Begin, v1.End, l1.Begin, l1.End)
            Assert.IsTrue(v1.Begin.DistanceTo(result) = 3)

            result = Algorithm.FindFirstOf(v1.Begin, v1.End, v2.Begin, v2.End, New equal_twice)
            Assert.IsTrue(v1.Begin.DistanceTo(result) = 2)

        End Sub
        <Test()> _
        Public Sub generate_it()
            Dim v1 As New List(Of Integer)(New Integer() {0, 0, 0, 0, 0, 0, 0, 0, 0, 0})

            Algorithm.Generate(v1.Begin, v1.End, New IntGenerator())
            Assert.IsTrue(TestUtil.equal(v1, New Integer() {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}))
        End Sub
        <Test()> _
        Public Sub generate_n()
            Dim v1 As New List(Of Integer)(New Integer() {0, 0, 0, 0, 0, 0, 0, 0, 0, 0})

            Algorithm.GenerateN(v1.Begin, 10, New IntGenerator())
            Assert.IsTrue(TestUtil.equal(v1, New Integer() {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}))
        End Sub
        <Test()> _
        Public Sub includes()
            'vectors sorted with less
            Dim v1a As New List(Of Integer)(new Integer() {-2, -1, 0, 1, 2, 3, 4})
            Dim v1b As New LinkedList(Of Integer)(New Integer() {-2, -1, 0, 1, 2, 3})

            'vectors sorted with greater:
            Dim v2a As New List(Of Integer)(new Integer() {4, 3, 2, 1, 0, -1})
            Dim v2b As New LinkedList(Of Integer)(New Integer() {2, 1, 0, -1, -2})

            'vectors sorted with abs_mod_less
            Dim v3a As New List(Of Integer)(new Integer() {0, 1, 2, 3, 4})
            Dim v3b As New LinkedList(Of Integer)(New Integer() {0, -1, 1, -2, 2, 3})

            Assert.IsTrue(Algorithm.Includes(v1a.Begin, v1a.End, v1b.Begin, v1b.End, Compare.Less(Of Integer)()))
            Assert.IsFalse(Algorithm.Includes(v2a.Begin, v2a.End, v2b.Begin, v2b.End, Compare.Greater(Of Integer)()))
            Assert.IsFalse(Algorithm.Includes(v3a.Begin, v3a.End, v3b.Begin, v3b.End, New mod_less_int))
        End Sub
        <Test()> _
        Public Sub sort()
            Dim v1 As New List(Of Integer)(new Integer() {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50})
            Dim v2 As New List(Of Integer)
            Dim v3 As New List(Of Integer)
            Algorithm.Copy(v1.RBegin, v1.REnd, v2.AddInserter())
            Algorithm.Copy(v1.Begin, v1.End, v3.AddInserter())
            Algorithm.RandomShuffle(v1.Begin(), v1.End())
            Algorithm.Sort(v1.Begin(), v1.End(), Compare.Less(Of Integer)())
            Assert.IsFalse(TestUtil.mismatch(v1, v3))

            Algorithm.Sort(v1.Begin, v1.End, Compare.Greater(Of Integer)())
            Assert.IsFalse(TestUtil.mismatch(v1, v2))

            'retest with a small vector, as this will trigger a different control path
            Dim v4 As New List(Of Integer)(new Integer() {0, 1, 1, 2, 3, 4, 5, 6, 7, 8})
            Dim v5 As New List(Of Integer)
            Algorithm.Copy(v4.Begin, v4.End, v5.AddInserter())

            Algorithm.RandomShuffle(v4.Begin, v4.End())

            Algorithm.Sort(v4.Begin, v4.End, Compare.Less(Of Integer)())

            Assert.IsFalse(TestUtil.mismatch(v4, v5))

        End Sub
        <Test()> _
        Public Sub merge()
            'vectors sorted with less
            Dim v1a As New List(Of Integer)(new Integer() {0, 1, 2, 3, 4, 5})
            Dim v1b As New LinkedList(Of Integer)(New Integer() {-5, -4, -3, -2, -1, 0})

            'vectors sorted with greater:
            Dim v2a As New List(Of Integer)(new Integer() {5, 4, 3, 2, 1, 0})
            Dim v2b As New LinkedList(Of Integer)(New Integer() {0, -1, -2, -3, -4, -5})

            'vectors sorted with abs_mod_less
            Dim v3a As New List(Of Integer)(new Integer() {0, 1, 2, 3, 4, 5})
            Dim v3b As New LinkedList(Of Integer)(New Integer() {0, -1, -2, -3, -4, -5})

            Dim v1mod As New List(Of Integer)
            Dim v1mod_exp As New List(Of Integer)(new Integer() {-5, -4, -3, -2, -1, 0, 0, 1, 2, 3, 4, 5})
            Algorithm.Merge(v1a.Begin, v1a.End, v1b.Begin, v1b.End, v1mod.AddInserter(), Compare.Less(Of Integer)())
            Assert.IsTrue(TestUtil.equal(v1mod, v1mod_exp))

            Dim v2mod As New List(Of Integer)
            Dim v2mod_exp As New List(Of Integer)(New Integer() {5, 4, 3, 2, 1, 0, 0, -1, -2, -3, -4, -5})
            Algorithm.Merge(v2a.Begin, v2a.End, v2b.Begin, v2b.End, v2mod.AddInserter(), Compare.Greater(Of Integer)())
            Assert.IsTrue(TestUtil.equal(v2mod, v2mod_exp))

            Dim v3mod As New List(Of Integer)
            Algorithm.Merge(v3a.Begin, v3a.End, v3b.Begin, v3b.End, v3mod.AddInserter(), New mod_less_int)
            Assert.IsTrue(TestUtil.equal(v3mod, 0, 0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5))

        End Sub
        <Test()> _
        Public Sub swap_ranges()
            Dim v1 As New List(Of Integer)(New Integer() {6, 6, 6, 6, 6, 6, 6, 6})
            Dim v11 As New List(Of Integer)(v1)
            Dim v2 As New LinkedList(Of Integer)(New Integer() {0, 2, 5, 4, 8, 9, 7, 2})
            Dim v22 As New List(Of Integer)(v2)

            Algorithm.SwapRanges(v1.Begin, v1.End, v2.Begin)
            Assert.IsFalse(TestUtil.mismatch(v1, v22))
            Assert.IsFalse(TestUtil.mismatch(v2, v11))
        End Sub
        <Test()> _
        Public Sub reverse()
            reverse_rnd_it()
            reverse_bidit()
        End Sub
        Private Shared Sub reverse_rnd_it()
            Dim v1 As New List(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, 6, 7, 8, 9})
            Dim v2 As New List(Of Integer)(New Integer() {9, 8, 7, 6, 5, 4, 3, 2, 1, 0})

            Algorithm.Reverse(v1.Begin, v1.End)
            Assert.IsTrue(TestUtil.equal(v1, v2))
        End Sub
        Private Shared Sub reverse_bidit()
            Dim v1 As New LinkedList(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, 6, 7, 8, 9})
            Dim v2 As New LinkedList(Of Integer)(New Integer() {9, 8, 7, 6, 5, 4, 3, 2, 1, 0})

            Algorithm.Reverse(v1.Begin, v1.End)
            Assert.IsTrue(TestUtil.equal(v1, v2))
        End Sub
        <Test()> _
        Public Sub reverse_copy()
            Dim v1 As New List(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, 6, 7, 8, 9})
            Dim v2 As New List(Of Integer)
            Algorithm.ReverseCopy(v1.Begin, v1.End, v2.AddInserter())
            Assert.IsFalse(TestUtil.mismatch(v2, New List(Of Integer)(New Integer() {9, 8, 7, 6, 5, 4, 3, 2, 1, 0})))
        End Sub
        <Test()> _
        Public Sub rotate_copy()
            Dim v1 As New List(Of Integer)(New Integer() {-3, -2, -1, 0, 1, 2, 3, 4, 5})
            Dim v2 As New List(Of Integer)
            Algorithm.RotateCopy(v1.Begin, v1.Begin.Add(3), v1.End, v2.AddInserter())
            Assert.IsFalse(TestUtil.mismatch(v2, New List(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, -3, -2, -1})))
        End Sub
        Private Shared Sub rotate_fwd_it()
            Dim v1 As New List(Of Integer)(New Integer() {-3, -2, -1, 0, 1, 2, 3, 4, 5})
            Dim v2 As New List(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, -3, -2, -1})

            Algorithm.Rotate(Of Integer, ForwardIteratorProxy(Of Integer))(New ForwardIteratorProxy(Of Integer)(v1.Begin), New ForwardIteratorProxy(Of Integer)(v1.Begin + 3), New ForwardIteratorProxy(Of Integer)(v1.End))

            Assert.IsFalse(TestUtil.mismatch(v1, v2))
        End Sub
        Private Shared Sub rotate_bidit_it()
            Dim v1 As New List(Of Integer)(New Integer() {-3, -2, -1, 0, 1, 2, 3, 4, 5})
            Dim v2 As New List(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, -3, -2, -1})

            Algorithm.Rotate(Of Integer, BidirectionalIteratorProxy(Of Integer))(New BidirectionalIteratorProxy(Of Integer)(v1.Begin), New BidirectionalIteratorProxy(Of Integer)(v1.Begin + 3), New BidirectionalIteratorProxy(Of Integer)(v1.End))

            Assert.IsFalse(TestUtil.mismatch(v1, v2))
        End Sub
        Private Shared Sub rotate_rnd_it()
            Dim v11 As New List(Of Integer)(New Integer() {-3, -2, -1, 0, 1, 2, 3, 4, 5})
            Dim v12 As New List(Of Integer)(New Integer() {-3, -2, -1, 0, 1, 2, 3, 4, 5})
            Dim v21 As New List(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, -3, -2, -1})
            Dim v22 As New List(Of Integer)(New Integer() {2, 3, 4, 5, -3, -2, -1, 0, 1})

            Algorithm.Rotate(Of Integer, ListTIterator(Of Integer))(v11.Begin, v11.Begin + 3, v11.End)
            Assert.IsFalse(TestUtil.mismatch(v11, v21))

            Algorithm.Rotate(Of Integer, ListTIterator(Of Integer))(v12.Begin, v12.Begin + 5, v12.End)
            Assert.IsFalse(TestUtil.mismatch(v12, v22))
        End Sub

        <Test()> _
        Public Sub rotate()
            rotate_fwd_it()
            rotate_bidit_it()
            rotate_rnd_it()
        End Sub
        <Test()> _
        Public Sub inplace_merge()
            Dim v11 As New List(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, -5, -4, -3, -2, -1, 0})
            Dim v12 As New LinkedList(Of Integer)(New Integer() {-5, -4, -3, -2, -1, 0, 0, 1, 2, 3, 4, 5})
            Algorithm.InplaceMerge(v11.Begin, Algorithm.Find(v11.Begin, v11.End, -5), v11.End, Compare.Less(Of Integer)())
            Assert.IsFalse(TestUtil.mismatch(v11, v12))

            Dim v21 As New List(Of Integer)(New Integer() {5, 4, 3, 2, 1, 0, 0, -1, -2, -3, -4, -5})
            Dim v22 As New LinkedList(Of Integer)(New Integer() {5, 4, 3, 2, 1, 0, 0, -1, -2, -3, -4, -5})
            Algorithm.InplaceMerge(v21.Begin, Algorithm.Find(v21.Begin, v21.End, 0).Add(-1), v21.End, Compare.Greater(Of Integer)())
            Assert.IsFalse(TestUtil.mismatch(v21, v22))

            Dim v31 As New List(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, 0, -1, -2, -3, -4, -5})
            Dim v32 As New LinkedList(Of Integer)(New Integer() {0, 0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5})
            Algorithm.InplaceMerge(v31.Begin, v31.Begin().Add(6), v31.End, New mod_less_int)
            Assert.IsFalse(TestUtil.mismatch(v31, v32))
        End Sub
        <Test()> _
        Public Sub lexicographical_compare()
            Dim v1 As New List(Of Integer)(new Integer() {0, 5, 10, 15, 20, 25})
            Dim l2 As New List(Of Integer)(new Integer() {0, 5, 10, 15, 20, 25, 30})
            Dim v2 As New List(Of Integer)(new Integer() {0, 10, 20, 30, 40, 50})

            Assert.IsFalse(Algorithm.LexicographicalCompare(v1.Begin, v1.End, v1.Begin, v1.End, Compare.Less(Of Integer)()))
            Assert.IsTrue(Algorithm.LexicographicalCompare(v1.Begin, v1.End, l2.Begin, l2.End, Compare.Less(Of Integer)()))
            Assert.IsTrue(Algorithm.LexicographicalCompare(v1.Begin, v1.End, v2.Begin, v2.End, New equal_twice))
        End Sub
        <Test()> _
        Public Sub max()
            Assert.AreEqual(4, Algorithm.Max(2, 4, Compare.Less(Of Integer)()))
            Assert.AreNotEqual(2, Algorithm.Max(2, 4, Compare.Less(Of Integer)()))
        End Sub
        <Test()> _
       Public Sub min()
            Assert.AreEqual(2, Algorithm.Min(2, 4, Compare.Less(Of Integer)()))
        End Sub
        <Test()> _
        Public Sub max_element()
            Dim v1 As New List(Of Integer)(New Integer() {0, 5, 10, 15, 20, 25, -6, -8, -99, -5})
            Assert.AreEqual(Algorithm.MaxElement(Of Integer, ListTIterator(Of Integer))(v1.Begin, v1.End).Value, 25)
            Assert.AreEqual(Algorithm.MaxElement(v1.Begin, v1.End, New mod_less_int).Value, -99)
        End Sub
        <Test()> _
        Public Sub min_element()
            Dim v1 As New List(Of Integer)(New Integer() {0, 5, 10, 15, 20, 25, -6, -8, -99, -5})
            Assert.AreEqual(Algorithm.MinElement(Of Integer, ListTIterator(Of Integer))(v1.Begin, v1.End).Value, -99)
            Assert.AreEqual(Algorithm.MinElement(v1.Begin, v1.End, New mod_less_int).Value, 0)
        End Sub
        <Test()> _
        Public Sub next_permutation()
            Dim v1 As New List(Of Integer)(New Integer() {-3, -2, -1, 0, 1, 2, 3})

            Assert.IsTrue(Algorithm.NextPermutation(v1.Begin, v1.End, New mod_less_int))
            Assert.IsFalse(TestUtil.mismatch(v1, New Integer() {-3, -2, -1, 0, 1, 3, 2}))

            Assert.IsTrue(Algorithm.NextPermutation(v1.Begin, v1.End, New mod_less_int))
            Assert.IsFalse(TestUtil.mismatch(v1, New Integer() {-3, -2, -1, 0, 2, 1, 3}))

            Assert.IsTrue(Algorithm.NextPermutation(v1.Begin, v1.End, New mod_less_int))
            Assert.IsFalse(TestUtil.mismatch(v1, New Integer() {-3, -2, -1, 0, 2, 3, 1}))

        End Sub
        <Test()> _
        Public Sub nth_element()
            Dim v1 As New List(Of Integer)(new Integer() {0, 1, 2, 3, 4, 5, 6, 7, 8, 9})
            Algorithm.RandomShuffle(v1.Begin, v1.End)

            Dim nth_elem As ListTIterator(Of Integer) = _
                 v1.Begin + 4


            Algorithm.NthElement(v1.Begin, nth_elem, v1.End, Compare.Less(Of Integer)())

            Dim nth_elemVal As Integer = nth_elem.Value
            Assert.AreEqual(nth_elem.Value, 4)

            ' Test that all before 9 are less and behind 9 are greater!
            Assert.AreEqual(Algorithm.FindIf(v1.Begin, nth_elem, Bind.Second(Compare.Greater(Of Integer)(), nth_elemVal)), nth_elem)
            Assert.AreEqual(Algorithm.FindIf(nth_elem, v1.End, Bind.Second(Compare.Less(Of Integer)(), nth_elemVal)), v1.End)

        End Sub
        <Test()> _
        Public Sub partial_sort_copy()
            Dim v1 As New List(Of Integer)(new Integer() {4, 10, 70, 30, 10, 69, 96, 7})
            Dim v2 As New List(Of Integer)(new Integer() {0, 0, 0, 0})

            Algorithm.PartialSortCopy(v1.Begin, v1.End, v2.Begin, v2.End, Compare.Less(Of Integer)())

            Assert.IsFalse(TestUtil.mismatch(v2, New Integer() {4, 7, 10, 10}))
        End Sub
        <Test()> _
        Public Sub partition()

            Dim num As Integer = 5
            Dim v1 As New List(Of Integer)(New Integer() {0, 1, 2, 3, 4, 5, 6, 7, 8, 9})

            'test fwd it version
            Algorithm.RandomShuffle(v1.Begin, v1.End)
            Dim res As ListTIterator(Of Integer) = _
                Algorithm.Partition(v1.Begin, v1.End, Bind.Second(Compare.Greater(Of Integer)(), num))

            Dim f As ListTIterator(Of Integer) = Algorithm.FindIf(v1.Begin, v1.End, Bind.Second(Compare.LessEqual(Of Integer)(), num))
            Assert.AreEqual(Algorithm.FindIf(v1.Begin, f, Bind.Second(Compare.LessEqual(Of Integer)(), num)), f)
            Assert.AreEqual(Algorithm.FindIf(f, v1.End, Bind.Second(Compare.Greater(Of Integer)(), num)), v1.End)

            'test bidit it version
            Algorithm.RandomShuffle(v1.Begin, v1.End)
            Algorithm.Partition(New BidirectionalIteratorProxy(Of Integer)(v1.Begin), New BidirectionalIteratorProxy(Of Integer)(v1.End), Bind.Second(Compare.Greater(Of Integer)(), num))

            f = Algorithm.FindIf(v1.Begin, v1.End, Bind.Second(Compare.LessEqual(Of Integer)(), num))
            Assert.AreEqual(Algorithm.FindIf(v1.Begin, f, Bind.Second(Compare.LessEqual(Of Integer)(), num)), f)
            Assert.AreEqual(Algorithm.FindIf(f, v1.End, Bind.Second(Compare.Greater(Of Integer)(), num)), v1.End)


        End Sub
        <Test()> _
        Public Sub partition2()
            Dim v1 As New List(Of Integer)(New Integer() {1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
            Algorithm.Partition(v1.Begin, v1.End, Compose.FGx(Bind.Second(Compare.EqualTo(Of Integer)(), 0), Bind.Second(New mod_int, 2)))

            Assert.IsTrue(TestUtil.equal(v1, 10, 2, 8, 4, 6, 5, 7, 3, 9, 1))
        End Sub

        <Test()> _
        Public Sub prev_permutation()
            Dim v1 As New List(Of Integer)(New Integer() {1, 5, 10})
            Assert.IsFalse(Algorithm.PrevPermutation(v1.Begin, v1.End(), Compare.Less(Of Integer)()))
            Assert.IsFalse(TestUtil.mismatch(v1, New List(Of Integer)(New Integer() {10, 5, 1})))

            v1 = New List(Of Integer)(New Integer() {-3, -2, -1, 0, 1, 2, 3})
            Assert.IsTrue(Algorithm.PrevPermutation(v1.Begin, v1.End(), New mod_less_int))
            Assert.IsFalse(TestUtil.mismatch(v1, New List(Of Integer)(New Integer() {-3, -2, 1, 3, 2, -1, 0})))

            Assert.IsTrue(Algorithm.PrevPermutation(v1.Begin, v1.End(), New mod_less_int))
            Assert.IsFalse(TestUtil.mismatch(v1, New List(Of Integer)(New Integer() {-3, -2, 1, 3, 2, 0, -1})))

            Assert.IsTrue(Algorithm.PrevPermutation(v1.Begin, v1.End(), New mod_less_int))
            Assert.IsFalse(TestUtil.mismatch(v1, New List(Of Integer)(New Integer() {-3, -2, 1, 3, -1, 2, 0})))
        End Sub
        <Test()> _
        Public Sub replace_if()
            Dim v1 As New List(Of Integer)(New Integer() {7, 1, 9, 2, 0, 7, 7, 3, 4, 6, 8, 5, 7, 7})
            Algorithm.ReplaceIf(v1.Begin(), v1.End(), Bind.Second(Compare.Greater(Of Integer)(), 6), 77)
            Assert.IsFalse(TestUtil.mismatch(v1, New List(Of Integer)(New Integer() {77, 1, 77, 2, 0, 77, 77, 3, 4, 6, 77, 5, 77, 77})))
        End Sub
        <Test()> _
        Public Sub replace()
            Dim v1 As New List(Of Integer)(New Integer() {7, 1, 9, 2, 0, 7, 7, 3, 4, 6, 8, 5, 7, 7})
            Algorithm.Replace(v1.Begin(), v1.End(), 7, 77)
            Assert.IsFalse(TestUtil.mismatch(v1, New List(Of Integer)(New Integer() {77, 1, 9, 2, 0, 77, 77, 3, 4, 6, 8, 5, 77, 77})))
        End Sub
        <Test()> _
        Public Sub replace_copy_if()
            Dim v1 As New List(Of Integer)(new Integer() {7, 1, 9, 2, 0, 7, 7, 3, 4, 6, 8, 5, 7, 7})
            Dim v2 As New List(Of Integer)
            Algorithm.ReplaceCopyIf(v1.Begin(), v1.End(), v2.AddInserter(), Bind.Second(Compare.Greater(Of Integer)(), 6), 77)
            Assert.IsFalse(TestUtil.mismatch(v2, New List(Of Integer)(New Integer() {77, 1, 77, 2, 0, 77, 77, 3, 4, 6, 77, 5, 77, 77})))
        End Sub
        <Test()> _
        Public Sub replace_copy()
            Dim v1 As New List(Of Integer)(new Integer() {7, 1, 9, 2, 0, 7, 7, 3, 4, 6, 8, 5, 7, 7})
            Dim v2 As New List(Of Integer)
            Algorithm.ReplaceCopy(v1.Begin(), v1.End(), v2.AddInserter(), 7, 77)
            Assert.IsFalse(TestUtil.mismatch(v2, New List(Of Integer)(New Integer() {77, 1, 9, 2, 0, 77, 77, 3, 4, 6, 8, 5, 77, 77})))
        End Sub
        <Test()> _
        Public Sub stable_partition()
            Dim v1a As New List(Of Integer)(new Integer() {5, 1, 9, 2, 0, 5, 7, 3, 4, 5, 8, 5, 5, 5, 10, 6})

            Algorithm.StablePartition(v1a.Begin, v1a.End, Bind.Second(Compare.Greater(Of Integer)(), 5))

            Assert.IsFalse(TestUtil.mismatch(v1a, New List(Of Integer)(New Integer() {9, 7, 8, 10, 6, 5, 1, 2, 0, 5, 3, 4, 5, 5, 5, 5})))

        End Sub
        <Test()> _
        Public Sub stable_sort()
            Dim n0_1 As New TestInteger(0)
            Dim n2_1 As New TestInteger(2)
            Dim n4_1 As New TestInteger(4)
            Dim n6_1 As New TestInteger(6)
            Dim n8_1 As New TestInteger(8)
            Dim n10_1 As New TestInteger(10)

            Dim n0_2 As New TestInteger(0)
            Dim n2_2 As New TestInteger(2)
            Dim n4_2 As New TestInteger(4)
            Dim n6_2 As New TestInteger(6)
            Dim n8_2 As New TestInteger(8)
            Dim n10_2 As New TestInteger(10)


            Dim v1 As New List(Of TestInteger)(New TestInteger() { _
                n0_1, _
                n2_1, _
                n4_1, _
                n6_1, _
                n8_1, _
                n10_1, _
                n0_2, _
                n2_2, _
                n4_2, _
                n6_2, _
                n8_2, _
                n10_2 _
                })

            ' Test sorting
            Dim extractInt As IUnaryFunction(Of TestInteger, Integer) = _
                Functional.PtrFun(Of TestInteger, Integer)(AddressOf TestInteger.GetInt)

            Dim less As IBinaryFunction(Of TestInteger, TestInteger, Boolean) = _
                Compose.FGxHy(Of TestInteger, TestInteger, Integer, Integer, Boolean)(Compare.Less(Of Integer)(), extractInt, extractInt)

            Algorithm.StableSort(v1.Begin, v1.End, less)

            Dim vExpected As New List(Of TestInteger)(New TestInteger() {n0_1, n0_2, n2_1, n2_2, n4_1, n4_2, n6_1, n6_2, n8_1, n8_2, n10_1, n10_2})

            Assert.AreEqual(v1.Count(), vExpected.Count())
            Assert.IsTrue(Algorithm.Equal(v1.Begin, v1.End, vExpected.Begin))

        End Sub

        Private Class TestInteger
            Public Sub New(ByVal i As Integer)
                Me.i = i
            End Sub
            Public ReadOnly Property Int() As Integer
                Get
                    Return i
                End Get
            End Property
            Public Shared Function GetInt(ByVal ii As TestInteger) As Integer
                Return ii.Int
            End Function
            Public i As Integer = 0
            Public Overrides Function ToString() As String
                Return String.Format("{0} - {1}", Me.GetHashCode, i)
            End Function
        End Class

        <Test()> _
        Public Sub unique_copy()
            Dim v1 As New List(Of Integer)(New Integer() {5, -5, 5, -5, 4, 4, 4, 7, 10, 10, 10, 10, 10, 10})


            'inplace unique
            Algorithm.UniqueCopy(v1.Begin, v1.Begin() + 8, v1.Begin() + 8, Compare.EqualTo(Of Integer)())
            Assert.IsFalse(TestUtil.mismatch(v1, New List(Of Integer)(New Integer() {5, -5, 5, -5, 4, 4, 4, 7, 5, -5, 5, -5, 4, 7})))
            Dim v2 As New List(Of Integer)
            v2.Resize(v1.Count)
            Algorithm.UniqueCopy(v1.Begin, v1.End(), v2.Begin(), New abs_mod_equal)
            v2.Remove(Algorithm.RemoveIf(v2.Begin, v2.End, Functional.IsDefault(Of Integer)()), v2.End())
            Assert.IsFalse(TestUtil.mismatch(v2, New List(Of Integer)(New Integer() {5, 4, 7, 5, 4, 7})))
        End Sub
        <Test()> _
        Public Sub unique()
            Dim v1 As New List(Of Integer)(new Integer() {5, -5, 5, -5, 4, 4, 4, 7, 10, 10, 10, 10, 10, 10})
            Dim v2 As New List(Of Integer)(new Integer() {5, -5, 5, -5, 4, 4, 4, 7, 10, 10, 10, 10, 10, 10})

            'Algorithm.sort(v1.begin, v1.end)
            v1.Remove(Algorithm.Unique(v1.Begin, v1.End, Compare.EqualTo(Of Integer)()), v1.End)
            Assert.IsFalse(TestUtil.mismatch(v1, New List(Of Integer)(New Integer() {5, -5, 5, -5, 4, 7, 10})))

            v2.Remove(Algorithm.Unique(v2.Begin, v2.End, New abs_mod_equal), v2.End)
            Assert.IsFalse(TestUtil.mismatch(v2, New List(Of Integer)(New Integer() {5, 4, 7, 10})))

        End Sub
        <Test()> _
        Public Sub accumulate()
            Dim v1 As Integer() = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
            Dim o As Integer = Algorithm.Accumulate(v1.Begin, v1.End, 0, Plus.Int32())
            Assert.AreEqual(o, 210)
        End Sub
        <Test()> _
        Public Sub adjacent_difference()
            Dim v1 As New List(Of Integer)
            Dim v2 As New List(Of Integer)
            Dim l1 As New List(Of Integer)(New Integer() {1, 4, 9, 16, 25, 36, 49, 64, 81, 100})

            Algorithm.AdjacentDifference(l1.Begin, l1.End, v1.AddInserter(), New minus_int)
            Assert.IsFalse(TestUtil.mismatch(v1, New List(Of Integer)(New Integer() {1, 3, 5, 7, 9, 11, 13, 15, 17, 19})))

            Algorithm.AdjacentDifference(l1.Begin, l1.End, v2.AddInserter(), New multiplies_int)
            Assert.IsFalse(TestUtil.mismatch(v2, New List(Of Integer)(New Integer() {1, 4, 36, 144, 400, 900, 1764, 3136, 5184, 8100})))

        End Sub
        <Test()> _
        Public Sub inner_product()
            Dim v1 As New List(Of Integer)(new Integer() {1, 2, 3, 4, 5, 6, 7})
            Dim l1 As New List(Of Integer)(new Integer() {1, 2, 3, 4, 5, 6, 7})

            Dim res As Integer = Algorithm.InnerProduct(v1.Begin, v1.End, l1.Begin, 0, New plus_int, New multiplies_int)
            Assert.AreEqual(res, 140)
        End Sub
        <Test()> _
        Public Sub partial_sum()
            Dim v1 As New List(Of Integer)(new Integer() {1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
            Dim l1 As New List(Of Integer)
            Algorithm.PartialSum(v1.Begin, v1.End, l1.AddInserter(), New plus_int)
            Assert.IsFalse(TestUtil.mismatch(l1, New List(Of Integer)(New Integer() {1, 3, 6, 10, 15, 21, 28, 36, 45, 55})))
        End Sub
        <Test()> _
        Public Sub TwoContainerRemove()
            Dim v As New List(Of Integer)
            For i As Integer = 0 To 9
                v.Add(i)
            Next
            Algorithm.RandomShuffle(v.Begin, v.End)

            Dim m As New Map(Of Integer, String)(Compare.Less(Of Integer)())
            Algorithm.Transform(v.Begin(), v.End(), m.InsertIterator(m.Begin()), New Vec2Map)

            m.Erase(0)
            m.Erase(2)
            m.Erase(4)
            m.Erase(6)
            m.Erase(8)

            'Dim callFind As IBinaryFunction(Of Map(Of Integer, String), Integer, Map(Of Integer, String).Iterator) = _
            '    Functional.PtrFun(Of Map(Of Integer, String), Integer, Map(Of Integer, String).Iterator)(AddressOf FindInMap)

            'Dim callFindBound As IUnaryFunction(Of Integer, Map(Of Integer, String).Iterator) = _
            '    Bind.First(callFind, m)

            'Dim compareFOrEndIt As UnaryFunction = Compose.FGx(Bind.First(Compare.EqualTo(Of bidirectional_iterator(Of pair(Of Integer, String)))(), m.end()), callFind)


            v.Remove(Algorithm.RemoveIf(v.Begin, v.End(), _
                                    Compose.FGx( _
                                         Bind.First(Compare.EqualTo(Of Map(Of Integer, String).Iterator)(), m.End()), _
                                            Bind.First(Functional.PtrFun(Of Map(Of Integer, String), Integer, Map(Of Integer, String).Iterator)(AddressOf FindInMap), m) _
                                                     ) _
                                  ), _
                        v.End())


            Algorithm.Sort(v.Begin, v.End)
            Assert.IsFalse(TestUtil.mismatch(v, New List(Of Integer)(New Integer() {1, 3, 5, 7, 9})))
        End Sub
        Private Shared Function FindInMap(Of Key, Value)(ByVal m As Map(Of Key, Value), ByVal k As Key) As Map(Of Key, Value).Iterator
            Return m.Find(k)
        End Function
    End Class
End Namespace


